package com.itlong.cloud.controller.engineer;

import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.app.engineer.AppEngineerDevicesDTO;
import com.itlong.cloud.POJO.DTO.app.engineer.AppEngineerThresholdDTO;
import com.itlong.cloud.POJO.PO.AppPublishInfoPO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.app.engineer.*;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.enumerate.LanguageTypeEnum;
import com.itlong.cloud.enumerate.PropertyEquipTypeEnum;
import com.itlong.cloud.enumerate.ecode.AppErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.equip.app.IAppDeviceServiceClient;
import com.itlong.cloud.equip.app.IAppEngineerDeviceServiceClient;
import com.itlong.cloud.noncore.app.IAppAppPublishInfoServiceClient;
import com.itlong.cloud.project.operate.IOperateAdManageServiceClient;
import com.itlong.cloud.project.operate.IOperatePushInfoServiceClient;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.app.IAppEngineerServiceClient;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * <desc>
 *      工程版APP控制器。
 * <desc/>
 *
 * @createDate 2017/11/8.
 */
@RestController
@RequestMapping("/engineer")
@RefreshScope
public class AppEngineerController {

    private static final Logger LOG = LoggerFactory.getLogger(AppEngineerController.class);

    //工程APP服务接口
    @Autowired
    IAppEngineerServiceClient iAppEgineerServiceClient;

    //工程APP设备服务接口
    @Autowired
    IAppEngineerDeviceServiceClient iAppEngineerDeviceServiceClient;

    //广告管理接口
    @Autowired
    IOperateAdManageServiceClient iOperateAdManageServiceClient;

    //消息推送接口
    @Autowired
    IOperatePushInfoServiceClient iOperatePushInfoServiceClient;

    @Autowired
    IAppAppPublishInfoServiceClient iAppAppPublishInfoServiceClient;

    //获取二维码
    @Autowired
    IAppDeviceServiceClient IAppDeviceServiceClient;

    @Value("${" + PlatformConstants.APP_REQUEST_PARAMS_ENCRYPT_KEY + "}")
    public String APP_REQUEST_PARAMS_ENCRYPT_KEY;

    /**
     * <desc>
     *      获取设备列表
     * </desc>
     *
     * @param projectId 项目id
     * @param token
     * @return
     * @author shengen.T
     * @createDate 2017/11/8
     */
    @RequestMapping(path = "/getDevices",method = RequestMethod.POST)
    @ResponseBody
    public MessageVO getDevices(String projectId, String token,String createTime, String sign){
        MessageVO messageVO;
        try{
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("projectId",projectId);
            params.put("createTime",createTime);
            //验证签名
            if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            //判断项目编号
            if(StringUtils.isBlank(projectId) || !projectId.matches("[0-9]{8}")){
                LOG.info("【工程版APP】获取设备列表_项目编号非法】" + projectId);
                return new MessageVO(AppErrorCodeEnum.PROJECT_NOT_MATCH.getErrorCode());
            }
            //从缓存中获取用户信息
            AppEngineerUserInfoVO userInfo=iAppEgineerServiceClient.retrieve(token);
            if(null == userInfo){
                return new MessageVO(AppErrorCodeEnum.USER_TOKEN_ERROR.getErrorCode());
            }
            Map<String,Object> deviceInfos=new HashMap<>();

            //门禁设备信息
            List<AppEngineerDoorDevicesVO> doorVOList =iAppEngineerDeviceServiceClient.getDoorDevices(userInfo.getUserId(),projectId);
            doorVOList.forEach(vo->{
                 StringHandlerUtil.formatString(vo);
             });
            deviceInfos.put("doorDevices",doorVOList);
            //电梯设备信息
            List<AppEngineerFloorDevicesVO> floorList=iAppEngineerDeviceServiceClient.getFloorDevices(userInfo.getUserId(),projectId);
            floorList.forEach(vo->{
                StringHandlerUtil.formatString(vo);
            });
            deviceInfos.put("floorDevices",floorList);

            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),deviceInfos);
        }catch ( Exception e){
            throw new DataAccessException("【工程版APP】获取设备列表失败",e);
        }
        return messageVO;
    }

     /**
      * <desc>
      *      获取设备机号。
      * <desc/>
      *
      * @param  devicesDTO 获取设备机号请求参数
      * @return
      * @author shengen.T
      * @createDate 2017/11/8
      */
    @RequestMapping(path = "/getDeviceId",method = RequestMethod.POST)
    @ResponseBody
    public MessageVO getDeviceId(AppEngineerDevicesDTO devicesDTO,String sign){
        MessageVO messageVO;
        try {
            //验证签名
            if(!Md5EncryptUtil.checkAppSign(devicesDTO,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            //判断项目编号
            if(StringUtils.isBlank(devicesDTO.getProjectId()) || !devicesDTO.getProjectId().matches("[0-9]{8}")){
                LOG.info("【工程版APP】获取设备机号_项目编号非法】" + devicesDTO.getProjectId());
                return new MessageVO(AppErrorCodeEnum.PROJECT_NOT_MATCH.getErrorCode());
            }
            //判断设备名称
            if(StringUtils.isBlank(devicesDTO.getDeviceName())){
                return new MessageVO(AppErrorCodeEnum.DEVICE_NAME_EMPTY_ERR.getErrorCode());
            }
            Integer deviceType = StringHandlerUtil.strToIntDef(devicesDTO.getDeviceType(),-1);
            //判断设备类型
            if((null == deviceType)||(( deviceType!= PropertyEquipTypeEnum.ELEVATOR.getType())&&(deviceType != PropertyEquipTypeEnum.ENTRANCE.getType())
                    &&(deviceType != PropertyEquipTypeEnum.OUT_CALL_CONTROLLER.getType()))){
                return new MessageVO(AppErrorCodeEnum.DEVICE_TYPE_INVALID_ERR.getErrorCode());
            }
            //从缓存中获取用户信息
            AppEngineerUserInfoVO userInfo=iAppEgineerServiceClient.retrieve(devicesDTO.getToken());
            if(null == userInfo){
                return new MessageVO(AppErrorCodeEnum.USER_TOKEN_ERROR.getErrorCode());
            }
            devicesDTO.setLoginUserId(userInfo.getUserId());
            Map<String,Object> devices=new HashMap<>();
            List<AppEngineerDevicesVO> devicesVOList =iAppEngineerDeviceServiceClient.getDeviceId(devicesDTO);
            devicesVOList.forEach(vo->{
                StringHandlerUtil.formatString(vo);
            });
            devices.put("devices",devicesVOList);
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),devices);
        }catch (Exception e){
            throw new DataAccessException("【工程版APP】获取设备机号失败",e);
        }
        return messageVO;
    }

     /**
      * <desc>
      *      上传阈值。
      * <desc/>
      *
      * @param  thresholdDTO 上传阈值请求参数
      * @return
      * @author shengen.T
      * @createDate 2017/11/8
      */
    @LoggerInfo(operateDesc = LogDescConstant.ENGINEER_APP_UPDATE_THRESHOLD)
    @RequestMapping(path = "/uploadData",method = RequestMethod.POST)
    @ResponseBody
    public MessageVO uploadData(AppEngineerThresholdDTO thresholdDTO,String sign){
        MessageVO messageVO;
        try {
            //验证签名
            if(!Md5EncryptUtil.checkAppSign(thresholdDTO,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            //判断设备唯一编码
            if(StringUtils.isBlank(thresholdDTO.getDeviceUnique())){
                return new MessageVO(AppErrorCodeEnum.DEVICE_UNIQUE_EMPTY_ERR.getErrorCode());
            }
            Integer deviceType = StringHandlerUtil.strToIntDef(thresholdDTO.getDeviceType(),-1);
            //判断设备类型
            if((null == deviceType)||(( deviceType!= PropertyEquipTypeEnum.ELEVATOR.getType())&&(deviceType != PropertyEquipTypeEnum.ENTRANCE.getType()))){
                return new MessageVO(AppErrorCodeEnum.DEVICE_TYPE_INVALID_ERR.getErrorCode());
            }
            //判断蓝牙开门阈值
            if(StringUtils.isBlank(thresholdDTO.getSignal())){
                return new MessageVO(AppErrorCodeEnum.OPEN_THRESHOLD_EMPTY_ERR.getErrorCode());
            }
            //从缓存中获取用户信息
            AppEngineerUserInfoVO userInfo=iAppEgineerServiceClient.retrieve(thresholdDTO.getToken());
            if(null == userInfo){
                return new MessageVO(AppErrorCodeEnum.USER_TOKEN_ERROR.getErrorCode());
            }
            Integer isSuccess = iAppEngineerDeviceServiceClient.uploadData(thresholdDTO);
            if(isSuccess<1){
                messageVO = new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode());
            }
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        }catch (Exception e){
            throw new DataAccessException("【工程版APP】上传阈值失败",e);
        }
        return messageVO;
    }


    /**
     * <desc>
     *     工程版APP,更新密码
     * </desc>
     * @param token
     * @param oldPswd
     * @param currentPswd
     * @return
     * @createDate 2017/10/10
     * @author shengen.T
     */
    @LoggerInfo(operateDesc = LogDescConstant.APP_UPDATE_PSWD)
    @RequestMapping(path = "/updatePswd",method = RequestMethod.POST)
    @ResponseBody
    public MessageVO updatePswd(String token,String oldPswd,String currentPswd,String createTime,String sign){
        try {
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("oldPswd",oldPswd);
            params.put("currentPswd",currentPswd);
            params.put("createTime",createTime);
            if (!Md5EncryptUtil.checkAppSign(params, sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }

            if (StringUtils.isBlank(oldPswd)||StringUtils.isBlank(currentPswd)||StringUtils.isBlank(createTime)){
                return  new MessageVO(AppErrorCodeEnum.NOT_PARAM.getErrorCode());
            }else if (oldPswd.length()<6||oldPswd.length()>16||currentPswd.length()<6||currentPswd.length()>16){
                return new MessageVO(AppErrorCodeEnum.PSWD_LENGTH_ERROR.getErrorCode());
            }
            AppEngineerUserInfoVO userInfo=iAppEgineerServiceClient.retrieve(token);
            if(null == userInfo){
                return new MessageVO(AppErrorCodeEnum.USER_TOKEN_ERROR.getErrorCode());
            }

            Integer result = iAppEgineerServiceClient.updatePswd(userInfo.getUserId(),
                    Md5EncryptUtil.md5(oldPswd), Md5EncryptUtil.md5(currentPswd));
            if(result>0){
                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
            }else{
                return new MessageVO(AppErrorCodeEnum.OLD_PSWD_ERROR.getErrorCode());
            }
        }catch (Exception e){
            throw new DataAccessException("【工程版APP_更新密码】更新密码失败",e);
        }
    }

    /**
     * <desc>
     *     APP端_首页版块，检测更新
     * </desc>
     * @param appType 类型,android/ios/iossdk/androidsdk/androidengineer
     * @param appSort 类别 test/official
     * @return
     * Date 2017/10/10
     * @author shengen.T
     */
    @RequestMapping(path = "/versionUpdate",method = RequestMethod.POST)
    @ResponseBody
    public MessageVO versionUpdate(String appType,String appSort,String createTime,String sign){
        MessageVO messageVO;
        try {
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("appType",appType);
            params.put("appSort",appSort);
            params.put("createTime",createTime);
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }else if (StringUtils.isBlank(appType)||StringUtils.isBlank(appSort)||StringUtils.isBlank(createTime)){
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            AppPublishInfoPO appPublishInfoPO = iAppAppPublishInfoServiceClient.getLatestAppPublishInfo(appType,appSort, LanguageTypeEnum.CHINESE.getLanguage());
            JSONObject js = new JSONObject();
            String appDownloadUrl="",appVersion="",mustUpdate="";
            if (appPublishInfoPO != null){
                appDownloadUrl = appPublishInfoPO.getAppDownUrl();
                appVersion = appPublishInfoPO.getAppVersion();
                mustUpdate = appPublishInfoPO.getMustUpdate()+"";
            }
            js.put("appDownloadUrl",appDownloadUrl);
            js.put("appVersion",appVersion);
            js.put("mustUpdate",mustUpdate);
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),js);
        }catch (Exception e){
            throw new DataAccessException("【工程版APP_最新版本】获取最新版本失败",e);
        }
        return  messageVO;
    }

    /**
     * <desc>
     *      获取二维码。
     * <desc/>
     *
     * @param token 凭证
     * @param projectId 项目编号
     * @param createTime 时间
     * @param tlv 仅二维码SDK调用时传
     * @param sign
     * @return
     * @author shengen.T
     * @createDate 2017-12-22
     */
    @RequestMapping(path="/getQrcode",method = RequestMethod.POST)
    public MessageVO getQrcode(String token,String projectId,String createTime,String tlv,String sign){
        MessageVO messageVO;
        try {
            //验签
            Map<String,String> params = new HashMap<>();
            params.put("projectId",projectId);
            params.put("createTime",createTime);
            params.put("tlv",tlv);
            //验证签名
            if(!Md5EncryptUtil.checkAppSign(params,sign,APP_REQUEST_PARAMS_ENCRYPT_KEY)){
                return  new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            AppEngineerUserInfoVO userInfo=iAppEgineerServiceClient.retrieve(token);
            if(null == userInfo){
                return new MessageVO(AppErrorCodeEnum.USER_TOKEN_ERROR.getErrorCode());
            }
            String resQrcode = IAppDeviceServiceClient.getAuthQrcode(projectId,tlv);
            Map<String,Object> qrcode=new HashMap<>();
            qrcode.put("qrcode",resQrcode);
            messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),qrcode);
        }catch (Exception e){
            throw new DataAccessException("【工程版APP】获取二维码失败",e);
        }
        return messageVO;
    }

    /**
     * <desc>
     *      获取二维码绑定的设备信息
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2020/02/26
     */
    @RequestMapping(path = "/getDeviceByQrCode", method = RequestMethod.POST)
    @ResponseBody
    public MessageVO getDeviceByQrCode(String qrCodeContent, String projectId, String token, String createTime, String sign) {
        try {
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("qrCodeContent", qrCodeContent);
            params.put("projectId", projectId);
            params.put("createTime", createTime);
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            if (StringUtils.isBlank(qrCodeContent) || StringUtils.isBlank(projectId) || StringUtils.isBlank(token)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            AppEngineerQrCodeDeviceVO appEngineerQrCodeDeviceVO = iAppEngineerDeviceServiceClient.getDeviceByQrCode(qrCodeContent);
            if (appEngineerQrCodeDeviceVO == null || StringUtils.isBlank(appEngineerQrCodeDeviceVO.getQrCodeContent())) {
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), "该二维码不存在此环境或已被禁用");
            }
            if (StringUtils.isNotBlank(appEngineerQrCodeDeviceVO.getDeviceUnique())) {
                appEngineerQrCodeDeviceVO.setDeviceUnique(StringHandlerUtil.getDeviceIdByDeviceUnique(appEngineerQrCodeDeviceVO.getDeviceUnique()));
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), appEngineerQrCodeDeviceVO);
        } catch (Exception e) {
            throw new DataAccessException("【工程版APP】获取二维码绑定的设备信息失败", e);
        }
    }

    /**
     * <desc>
     *      绑定设备与二维码
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2020/02/26
     */
    @LoggerInfo(operateDesc = LogDescConstant.ENGINEER_APP_BIND_DEVICE_QRCODE)
    @RequestMapping(path = "/bindingDeviceQrCode", method = RequestMethod.POST)
    @ResponseBody
    public MessageVO bindingDeviceQrCode(String qrCodeContent, String projectId, String deviceType, String sedanPlace, String deviceUnique, String floor, String token, String createTime, String sign) {
        try {
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("qrCodeContent", qrCodeContent);
            params.put("projectId", projectId);
            params.put("deviceType", deviceType);
            params.put("sedanPlace", sedanPlace);
            params.put("deviceUnique", deviceUnique);
            params.put("floor", floor);
            params.put("createTime", createTime);
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            if (StringUtils.isBlank(qrCodeContent) || StringUtils.isBlank(projectId) || StringUtils.isBlank(token) || StringUtils.isBlank(deviceType) || StringUtils.isBlank(deviceUnique)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (deviceUnique.length() > 4) {
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode(), "设备机号填写错误");
            }
            if (!"1".equals(deviceType) && !"2".equals(deviceType)) {
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode());
            }
            if ("1".equals(deviceType) && !"1".equals(sedanPlace) && !"2".equals(sedanPlace)) {
                return new MessageVO(BaseErrorCodeEnum.PARAM_ERR.getErrorCode());
            }
            if ("1".equals(deviceType) && "2".equals(sedanPlace) && StringUtils.isBlank(floor)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            AppEngineerUserInfoVO userInfo = iAppEgineerServiceClient.retrieve(token);
            if (null == userInfo) {
                return new MessageVO(AppErrorCodeEnum.USER_TOKEN_ERROR.getErrorCode());
            }
            AppEngineerQrCodeDeviceVO appEngineerQrCodeDeviceVO = iAppEngineerDeviceServiceClient.getDeviceByQrCode(qrCodeContent);
            if (appEngineerQrCodeDeviceVO == null || StringUtils.isBlank(appEngineerQrCodeDeviceVO.getQrCodeContent())) {
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), "该二维码不存在此环境或已被禁用");
            }
            deviceUnique = projectId + deviceType + StringHandlerUtil.formatStrLen(deviceUnique, "0", 4, false, false);
            Integer result = iAppEngineerDeviceServiceClient.bindingDeviceQrCode(qrCodeContent, projectId, deviceType, sedanPlace, deviceUnique, floor, userInfo.getUserId());
            if (result == -1) {
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), "物业平台暂未录入该云设备");
            }
            if (result == -2) {
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), "请及时刷新并选择正确的楼层");
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode());
        } catch (Exception e) {
            throw new DataAccessException("【工程版APP】绑定设备与二维码失败", e);
        }
    }

    /**
     * <desc>
     *      获取电梯设备的楼层
     * </desc>
     *
     * @return 标准格式化响应结果
     * @author wangzhi
     * @createDate 2020/03/11
     */
    @RequestMapping(path = "/getDeviceFloors", method = RequestMethod.POST)
    @ResponseBody
    public MessageVO getDeviceFloors(String projectId, String deviceUnique, String token, String createTime, String sign) {
        try {
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("projectId", projectId);
            params.put("deviceUnique", deviceUnique);
            params.put("createTime", createTime);
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            if (StringUtils.isBlank(deviceUnique) || StringUtils.isBlank(projectId) || StringUtils.isBlank(token)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            deviceUnique = projectId + "1" + StringHandlerUtil.formatStrLen(deviceUnique, "0", 4, false, false);
            List<String> floor = iAppEngineerDeviceServiceClient.getDeviceFloors(projectId, deviceUnique);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), floor);
        } catch (Exception e) {
            throw new DataAccessException("【工程版APP】获取电梯设备的楼层失败", e);
        }
    }

}

